package com.gangye;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Classname DateUtil
 * @Description 时间日期工具类
 * @Date 2020/4/3 16:02
 * @Created by gangye
 */
public class DateUtil {
    public static final String REGEX = "((19|20)[0-9]{2})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])";
    public static final String REGEX1 = "(\\d{4})-(\\d+)-(\\d+).*";
    public static final String TIME_REGEX = "^(?:[01]\\d|2[0-3])(?::[0-5]\\d){2}$";
    public static final String DATE_STR_TYPE = "yyyy-MM-dd";
    public static final String TIME_STR_TYPE = "HH:mm:ss";
    public static final String DATE_STR_TYPE_WITHOUT_LINE = "yyyyMMdd";
    public static final String TIME_STR_TYPE_WITHOUT_SYMBOL = "HHmmss";
    public static final String DATETIME_STR_TYPE = "yyyy-MM-dd HH:mm:ss";
    public static final String DATETIME_STR_TYPE_WITHOUT_SYMBOL = "yyyyMMddHHmmss";
    public static final String DATETIMETAMP_STR_TYPE = "yyyy-MM-dd HH:mm:ss SSS";
    public static final String DATETIMETAMP_STR_TYPE_WITHOUT_LINE = "yyyyMMddHHmmssSSS";
    public static final String DATE_STR_TYPE_WITH_CHINESE_CHAR = "yyyy年MM月dd日HH时mm分ss秒";

    //判断是否是HH:mm:ss类型的
    public static boolean isTimeFormat(String timeStr){
        Pattern pattern = Pattern.compile(TIME_REGEX);
        return pattern.matcher(timeStr).matches();
    }

    //根据传入的字符串判断所属的格式类型
    public static String getDateFormat(String dateStr){
        String dateFormat = null;
        int strlength = dateStr.length();
        if (strlength == DATE_STR_TYPE.length()){
            dateFormat = DATE_STR_TYPE;
        }else if(StringUtil.isNumStr(dateStr) && strlength == DATE_STR_TYPE_WITHOUT_LINE.length()){
            dateFormat = DATE_STR_TYPE_WITHOUT_LINE;
        }else if(strlength == DATETIME_STR_TYPE.length()){
            dateFormat = DATETIME_STR_TYPE;
        }else if(strlength == DATETIMETAMP_STR_TYPE.length()){
            dateFormat = DATETIMETAMP_STR_TYPE;
        }else if(strlength == TIME_STR_TYPE_WITHOUT_SYMBOL.length()){
            dateFormat = TIME_STR_TYPE_WITHOUT_SYMBOL;
        }else if(strlength == DATETIMETAMP_STR_TYPE_WITHOUT_LINE.length()){
            dateFormat = DATETIMETAMP_STR_TYPE_WITHOUT_LINE;
        }else if(strlength == DATETIME_STR_TYPE_WITHOUT_SYMBOL.length()){
            dateFormat = DATETIME_STR_TYPE_WITHOUT_SYMBOL;
        }else if(isTimeFormat(dateStr)){
            dateFormat = TIME_STR_TYPE;
        }
        return dateFormat;
    }

    //根据传入的字符串获得日期
    public static Date getDateByStr(String dateStr){
        SimpleDateFormat sdf = new SimpleDateFormat(getDateFormat(dateStr));
        try {
            return sdf.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }
    }

    //判断字符串是否是yyyy-MM-dd类型的
    public static boolean matchDateType(String timeStr){
        Pattern pattern = Pattern.compile(REGEX);
        Matcher matcher = pattern.matcher(timeStr);
        if (matcher.matches()) {
            pattern = Pattern.compile(REGEX1);
            matcher = pattern.matcher(timeStr);
            if (matcher.matches()) {
                int y = Integer.valueOf(matcher.group(1));
                int m = Integer.valueOf(matcher.group(2));
                int d = Integer.valueOf(matcher.group(3));
                if (d > 28) {
                    Calendar c = Calendar.getInstance();
                    c.set(y, m-1, 1);
                    int lastDay = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                    return (lastDay >= d);
                }
            }
            return true;
        }
        return false;
    }

    //获得传入日期的第二天的字符串
    public static String getNextDay(String dateStr){
        //先判断传入的字符串是否是yyyy-MM-dd类型的，且是否是正常日期
        if(matchDateType(dateStr)){
            SimpleDateFormat formatter = new SimpleDateFormat(DATE_STR_TYPE);
            Date date ;
            try {
                date = formatter.parse(dateStr);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                calendar.add(Calendar.DATE,1);//把日期往后增加一天.整数往后推一天,负数获得前一天
                date=calendar.getTime(); //获得传入时间的后一天
                return formatter.format(date);
            } catch (ParseException e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;
    }

    //获得带有汉字说明的时间日期字符串转化成yyy年MM月dd日HH时mm分ss秒格式
    public static String getDateStrWithChinaChar(String dateStr){
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_STR_TYPE_WITH_CHINESE_CHAR);
        SimpleDateFormat sdf1 = new SimpleDateFormat(getDateFormat(dateStr));
        try {
            Date date = sdf1.parse(dateStr);
            return sdf.format(date);
        } catch (ParseException e) {
            return null;
        }
    }

    //计算两个日期相差几天
    public static int getDayOfTwoDate(Date startDate,Date endDate){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        int startDay = calendar.get(Calendar.DAY_OF_YEAR);
        calendar.setTime(endDate);
        int endDay = calendar.get(Calendar.DAY_OF_YEAR);
        return endDay-startDay;
    }

    //获得传入日期的后几天or前几天(正整数为后，负整数为前)
    public static Date getWantDay(String dateStr, int day){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE,calendar.get(Calendar.DATE) + day);
        return calendar.getTime();
    }

    //获得传入日期的指定的前后几个月(正整数为后，负整数为前)
    public static Date getWantMonth(String dateStr, int month){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH,calendar.get(Calendar.MONTH) + month);
        return calendar.getTime();
    }

    //获得指定月份的最大的天数
    public static int getMaxDayOfMonth(String dateStr, int month){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH)+month,1);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    //获得传入日期的指定的前后几个月的第一天(正整数为后几个月，负整数为前几个月)
    public static Date getWantMonthFirstDay(String dateStr, int month){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH,calendar.get(Calendar.MONTH) + month);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        return calendar.getTime();
    }

    //获得传入日期的指定的前后几个月的最后一天(正整数为后几个月，负整数为前几个月)
    public static Date getWantMonthLastDay(String dateStr, int month){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MONTH,calendar.get(Calendar.MONTH) + month);
        calendar.set(Calendar.DAY_OF_MONTH,getMaxDayOfMonth(dateStr,month));
        return calendar.getTime();
    }

    //获得前后指定小时的时间
    public static Date getWantTimeHour(String dateStr, int hour){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR,calendar.get(Calendar.HOUR)+hour);
        return calendar.getTime();
    }

    //获得前后指定分钟的时间
    public static Date getWantTimeMintue(String dateStr, int mintue){
        Date date = getDateByStr(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE,calendar.get(Calendar.MINUTE)+mintue);
        return calendar.getTime();
    }

    //根据时间日期获得订单的生成
    public static String getOrderStart(){
        return new SimpleDateFormat(DATETIME_STR_TYPE_WITHOUT_SYMBOL).format(System.currentTimeMillis());
    }
}
